<template>
    <div>
      <div @change=""></div>
      <a id="downlink"></a>
    </div>
</template>

<script>
  var XLSX = require('xlsx');
    export default {
        name: "ExcelDaoChu",
      props:{
        myName:String, //表名
        myTitle:Array,//标题数组形式，['姓名','年龄']
        myTitleObj:Object,//标题对象形式(推荐能防顺序错误)，{name:'姓名',age:'年龄'}
        myData:Array,//导出的数据
        myClick:Boolean,//触发导出
        myRank:Array,//排序，['id','name','age'],给定key，未给定的key将不显示

      },
      mounted(){
        this.outFile = document.getElementById('downlink')
      },
      data(){
          return{
            excelData: [],
            outFile: [],  // 导出文件el
          }
      },
      watch:{
        myClick() {
          if(this.myClick){
            this.sureExcel()
          }
        },
      },
      methods:{
        sureExcel(){
          setTimeout(()=>{
            let rs=this.myData
            console.log(rs)
            if(!rs.length){
              this.$message({
                type: 'warning',
                message: '导出数据为空！'
              });
              return
            }
            let data = [{}]
            if(this.myTitle){//标题为数组形式
              let i=0
              for (let k in rs[0]) {
                data[0][k] = this.myTitle[i]||''
                i++
              }
              data = data.concat(rs)
            }else if(this.myTitleObj){//标题为对象形式
              console.log('导出2')
              for (let k in rs[0]) {
                data[0][k] = this.myTitleObj[k]||''
              }
              data = data.concat(rs)
            }
            this.downloadExl(data, this.myName)
          },500)
        },
        downloadExl: function (json, downName, type) {  // 导出到excel
          console.log(json)
          let keyMap = [] // 获取键
          for (let k in json[0]) { //遍历标题
            keyMap.push(k)
          }
          // keyMap=['订单编号','下单时间','状态','实际金额','用户名','使用产品名','电话']
          console.info('keyMap', keyMap, json)
          let tmpdata = [], // 用来保存转换好的json
            jm=null;
          //v:当前json对象,i:json下标  k:当前json对象属性名对象,j:属性名下标
          if(this.myRank&&this.myRank.length){
             jm= json.map((v, i) => keyMap.map((k, j) =>
               Object.assign({}, {
                 v: v[this.myRank[j]],
                 position: (j > 25 ? this.getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
               })
            ))
          }else{
            console.log('导出2')

            jm= json.map((v, i) => keyMap.map((k, j) => Object.assign({}, {
                  v: v[k],
                  position: (j > 25 ? this.getCharCol(j) : String.fromCharCode(65 + j)) + (i + 1)
                })
            ))
          }

          console.log(jm)





           jm.reduce((prev, next) => prev.concat(next)).forEach(function (v) {
            tmpdata[v.position] = {
              v: v.v
            }
          })
          console.log(tmpdata)
          let outputPos = Object.keys(tmpdata)  // 设置区域,比如表格从A1到D10
          let tmpWB = {
            SheetNames: ['mySheet'], // 保存的表标题
            Sheets: {
              'mySheet': Object.assign({},
                tmpdata, // 内容
                {
                  '!ref': outputPos[0] + ':' + outputPos[outputPos.length - 1] // 设置填充区域
                })
            }
          }
          let tmpDown = new Blob([this.s2ab(XLSX.write(tmpWB,
            {bookType: (type === undefined ? 'xlsx' : type), bookSST: false, type: 'binary'} // 这里的数据是用来定义导出的格式类型
          ))], {
            type: ''
          })  // 创建二进制对象写入转换好的字节流
          var href = URL.createObjectURL(tmpDown)  // 创建对象超链接
          this.outFile.download = downName + '.xlsx'  // 下载名称
          this.outFile.href = href  // 绑定a标签
          this.outFile.click()  // 模拟点击实现下载
          console.log(href)
          setTimeout(function () {  // 延时释放
            URL.revokeObjectURL(tmpDown) // 用URL.revokeObjectURL()来释放这个object URL
          }, 10000)
        },
        s2ab: function (s) { // 字符串转字符流
          var buf = new ArrayBuffer(s.length)
          var view = new Uint8Array(buf)
          for (var i = 0; i !== s.length; ++i) {
            view[i] = s.charCodeAt(i) & 0xFF
          }
          return buf
        },
        getCharCol: function (n) { // 将指定的自然数转换为26进制表示。映射关系：[0-25] -> [A-Z]。
          let s = ''
          let m = 0
          while (n > 0) {
            m = n % 26 + 1
            s = String.fromCharCode(m + 64) + s
            n = (n - m) / 26
          }
          return s
        },
        fixdata: function (data) {  // 文件流转BinaryString
          var o = ''
          var l = 0
          var w = 10240
          for (; l < data.byteLength / w; ++l) {
            o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w, l * w + w)))
          }
          o += String.fromCharCode.apply(null, new Uint8Array(data.slice(l * w)))
          return o
        },
      }
    }
</script>

<style scoped>

</style>
